package com.example.cinemasystemv2.service;

import com.example.cinemasystemv2.entity.Order;
import com.example.cinemasystemv2.entity.Screening;
import com.example.cinemasystemv2.entity.Ticket;
import com.example.cinemasystemv2.repository.TicketRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Service
public class TicketService {
    
    @Autowired
    private TicketRepository ticketRepository;
    
    @Autowired
    private SystemLogService systemLogService;
    
    @Autowired
    private ScreeningService screeningService;
    
    @Autowired
    private OrderService orderService;
    
    public List<Ticket> getAllTickets() {
        return ticketRepository.findAll();
    }
    
    public Optional<Ticket> getTicketById(Long id) {
        return ticketRepository.findById(id);
    }
    
    public Optional<Ticket> getTicketByTicketNumber(String ticketNumber) {
        return ticketRepository.findByTicketNumber(ticketNumber);
    }
    
    public List<Ticket> getTicketsByOrderId(String orderId) {
        return ticketRepository.findByOrderId(orderId);
    }
    
    public List<Ticket> getTicketsByScreeningId(Long screeningId) {
        return ticketRepository.findByScreeningId(screeningId);
    }
    
    public List<Ticket> getTicketsByDateRange(LocalDateTime startTime, LocalDateTime endTime) {
        return ticketRepository.findByCreatedAtBetween(startTime, endTime);
    }
    
    public Ticket saveTicket(Ticket ticket) {
        if (ticket.getCreatedAt() == null) {
            ticket.setCreatedAt(LocalDateTime.now());
        }
        Ticket savedTicket = ticketRepository.save(ticket);
        systemLogService.log("电影票保存: " + ticket.getTicketNumber(), "system", "SAVE_TICKET");
        return savedTicket;
    }
    
    public Ticket updateTicket(Ticket ticket) {
        Ticket updatedTicket = ticketRepository.save(ticket);
        systemLogService.log("电影票更新: " + ticket.getTicketNumber(), "system", "UPDATE_TICKET");
        return updatedTicket;
    }
    
    public void deleteTicket(Long id) {
        Optional<Ticket> ticketOpt = ticketRepository.findById(id);
        if (ticketOpt.isPresent()) {
            Ticket ticket = ticketOpt.get();
            ticketRepository.deleteById(id);
            systemLogService.log("电影票删除: " + ticket.getTicketNumber(), "system", "DELETE_TICKET");
        }
    }
    
    public boolean existsByTicketNumber(String ticketNumber) {
        return ticketRepository.existsByTicketNumber(ticketNumber);
    }
    
    public long countTicketsByScreeningId(Long screeningId) {
        return ticketRepository.countByScreeningId(screeningId);
    }
    
    public List<String> getSoldSeatsByScreeningId(Long screeningId) {
        return ticketRepository.findSeatNumbersByScreeningId(screeningId);
    }
    
    public List<Ticket> getTodayTickets() {
        LocalDateTime startOfDay = LocalDateTime.now().toLocalDate().atStartOfDay();
        LocalDateTime endOfDay = startOfDay.plusDays(1).minusSeconds(1);
        return getTicketsByDateRange(startOfDay, endOfDay);
    }
    
    public List<Ticket> getThisWeekTickets() {
        LocalDateTime startOfWeek = LocalDateTime.now().toLocalDate().atStartOfDay().minusDays(LocalDateTime.now().getDayOfWeek().getValue() - 1);
        LocalDateTime endOfWeek = startOfWeek.plusDays(7).minusSeconds(1);
        return getTicketsByDateRange(startOfWeek, endOfWeek);
    }
    
    public List<Ticket> getThisMonthTickets() {
        LocalDateTime startOfMonth = LocalDateTime.now().toLocalDate().withDayOfMonth(1).atStartOfDay();
        LocalDateTime endOfMonth = startOfMonth.plusMonths(1).minusSeconds(1);
        return getTicketsByDateRange(startOfMonth, endOfMonth);
    }
    
    public double getTotalSalesByDateRange(LocalDateTime startTime, LocalDateTime endTime) {
        List<Ticket> tickets = getTicketsByDateRange(startTime, endTime);
        return tickets.stream().mapToDouble(Ticket::getPrice).sum();
    }
    
    public long getTicketCountByDateRange(LocalDateTime startTime, LocalDateTime endTime) {
        return getTicketsByDateRange(startTime, endTime).size();
    }
    
    // 获取与订单关联的票据的详细信息，包括场次、电影和放映厅
    public Map<String, Object> getTicketDetails(Ticket ticket) {
        Map<String, Object> details = new HashMap<>();
        details.put("ticket", ticket);
        
        // 获取场次信息
        Optional<Screening> screeningOpt = screeningService.getScreeningById(ticket.getScreeningId());
        screeningOpt.ifPresent(screening -> {
            details.put("screening", screening);
            details.put("movie", screening.getMovie());
            details.put("room", screening.getRoom());
        });
        
        // 获取订单信息
        Optional<Order> orderOpt = orderService.getOrderByOrderId(ticket.getOrderId());
        orderOpt.ifPresent(order -> details.put("order", order));
        
        return details;
    }
}